Plotting brain mesh atlases in plotly

Introduction

Some times, you want to plot the 3d-surfaces from freesurfer. Here, it is easier to use data from freesurfer (like annot and colorlut files) to create colours for the vectors. The data is somewhat more complex than the 2d ggplot polygon version ggseg ggseg3d() will create a plotly plot, which is interactive, and provides another type of flexibility to the user. A lot of credit goes to A.M.Winkler and his Brainder work, which supplied us with the first examples of going from .srf to .ply files, and whose scripts massively aided us in making this work.

Basic use

The function ggseg3d(), is based in the plotly, it is recommended to get a little familiarized with with plotly.

Out-of-the-box, ggseg() works without supplying any extra information. It will create a base plot of the aparc (dkt) brain segmentations. All [...]_3d atlases have a built in colour column for default colour plotting of the segments.

library(ggseg)
library(magrittr)
library(dplyr)
library(tidyr)
ggseg3d()
ggseg3d(atlas=yeo7_3d)

Atlas data

The data is stored in tibbles, and looks like so:

yeo7_3d
## # A tibble: 4 x 3
##   surf     hemi  data             
##   <chr>    <chr> <list>           
## 1 inflated left  <tibble [10 × 7]>
## 2 inflated right <tibble [8 × 7]> 
## 3 white    left  <tibble [10 × 7]>
## 4 white    right <tibble [8 × 7]>

To grab all the data for a surface and hemisphere, you should reduce the data to one line, and then unnest()

yeo7_3d %>% 
  filter(surf == "inflated" & hemi == "right") %>% 
  unnest()
## # A tibble: 8 x 9
##   surf   hemi  atlas  roi   annot       label        mesh   area    colour
##   <chr>  <chr> <chr>  <chr> <chr>       <chr>        <list> <chr>   <chr> 
## 1 infla… right yeo7_… 0001  FreeSurfer… rh_FreeSurf… <list… <NA>    <NA>  
## 2 infla… right yeo7_… 0002  7Networks_1 rh_7Network… <list… visual  #a153…
## 3 infla… right yeo7_… 0003  7Networks_2 rh_7Network… <list… somato… #6fab…
## 4 infla… right yeo7_… 0004  7Networks_3 rh_7Network… <list… dorsal… #2c8b…
## 5 infla… right yeo7_… 0005  7Networks_4 rh_7Network… <list… ventra… #b77f…
## 6 infla… right yeo7_… 0006  7Networks_5 rh_7Network… <list… limbic  #e7ed…
## 7 infla… right yeo7_… 0007  7Networks_6 rh_7Network… <list… fronto… #edaf…
## 8 infla… right yeo7_… 0008  7Networks_7 rh_7Network… <list… default #e272…

External data supply

Particularly notice the mesh column, which is a list column of lists. In there is all the 6 vectors needed to create the mesh of the tri-surface plot. You’ll also need to notive the label, annot and area columns, which are likely the columns you will be matching on when proviging with your own data for colours. You need to be meticulous when fixing your data, be sure it matches. The function should give you a warning if it’s struggling to match something.

The column you want to use for colour, needs to be supplied to the colour option, and you’ll likely want to supply it to the text option, as this will add another line to the plotly hover information.

someData = yeo7_3d %>% 
  filter(surf == "inflated" & hemi == "right") %>% 
  unnest() %>% 
  select(area) %>% 
  na.omit() %>% 
  mutate(p = sample(seq(0,.5, length.out = 100 ), nrow(.)) %>% 
           round(2)) 
  
  ggseg3d(data = someData, atlas = yeo7_3d, colour = "p", text = "p")

Palettes

You can also change the palette. Choose from ALL the paletteer palettes, just use their name.

  ggseg3d(data = someData, atlas = yeo7_3d, colour = "p", text = "p", palette = "berlin")
  ggseg3d(data = someData, atlas = yeo7_3d, colour = "p", text = "p", palette = "RdBu")

You can also provide custom colour palettes either in hex or R-names

  ggseg3d(data = someData, atlas = yeo7_3d, 
          colour = "p", text = "p", 
          palette = c("forestgreen", "white", "firebrick"))
  ggseg3d(data = someData, atlas = yeo7_3d, 
          colour = "p", text = "p", palette = c("#ff0000", "#00ff00", "#0000ff"))

If you want to alter the colour of NA regions, supply na.colour

  ggseg3d(data = someData, atlas = yeo7_3d, 
          colour = "p", text = "p", 
          na.colour = "black", camera="medial")
  ggseg3d(data = someData, atlas = yeo7_3d, 
          colour = "p", text = "p", 
          na.colour = "#ffff00", camera="medial")

Camera

You can rotate away all you like. if you want to start from the medial view, you can use the camera option

  ggseg3d(data = someData, atlas=yeo7_3d, colour = "p", camera = "medial")

There is also a surface of the white-matter

 ggseg3d(atlas=yeo17_3d, surface="white")